#include "header.h"

int main()
{
    // 1. 创建监听的套接字
    int listenfd = socket(AF_INET , SOCK_STREAM , 0);
    ERROR_CHECK(listenfd , -1 , "socket");

    struct sockaddr_in serveraddr;
    memset(&serveraddr , 0 , sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(9090);
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    // 2. 绑定网络地址
    int ret = bind(listenfd , (const struct sockaddr *)&serveraddr , 
                   sizeof(serveraddr));
    ERROR_CHECK(ret , -1 , "bind");

    // 3. 监听新连接的到来
    int ret2 = listen(listenfd , 1);
    ERROR_CHECK(ret2 , -1 , "listen");

    // 服务器模型：循环迭代服务器
    while(1)
    {
        struct sockaddr_in clientaddr;
        memset(&clientaddr , 0 , sizeof(clientaddr));
        socklen_t len = sizeof(clientaddr);

        // 4. 获取到与对端进行通信的套接字 netfd ，它是 listenfd 的分身
        int netfd = accept(listenfd , (struct sockaddr *)&clientaddr , &len);
        ERROR_CHECK(netfd , -1 , "accept");

        // 与对端进行通信
        // msg 代表的是用户态发送缓冲区
        const char msg[1024] = "服务端已连接！";
        // 对于数组使用 sizeof 运算符
        // 获取的是数组的长度
        // 不是字符串的长度
        ret = send(netfd , msg , strlen(msg) , 0);
        printf("send %d bytes.\n" , ret);
        // 在发送数据时建议使用 strlen 来获取字符串的长度
        // 要注意获取其返回值
        
        // buff 代表的是用户态接收缓冲区
        char buff[1024] = {0};
        ret = recv(netfd , buff , sizeof(buff) , 0);
        printf("客户端：%s \n接收了 %d 字节数据\n" , buff , ret);
    }

    close(listenfd);

    return 0;

}
